import { EventEmitter } from 'events';
import { RepositoryFactory } from '../database/repositories/index.js';
import { Component, ComponentProp, ComponentExample, ComponentImport, Template } from '../database/models/index.js';
import { AntDesignScraper } from './AntDesignScraper.js';
import { AntDesignProScraper } from './AntDesignProScraper.js';
import { ProComponentsScraper } from './ProComponentsScraper.js';
import { AntDesignChartsScraper } from './AntDesignChartsScraper.js';
import { UniversalScraper } from './UniversalScraper.js';
import { DataConverter, type ComponentData, type TemplateData } from './DataConverter.js';
import type { ScrapingResult } from './BaseScraper.js';

/**
 * 数据收集进度信息
 */
export interface CollectionProgress {
  stage: string;
  current: number;
  total: number;
  currentTask?: string;
  message?: string;
  completed: string[];
  errors: string[];
}

/**
 * 数据收集结果
 */
export interface CollectionResult {
  success: boolean;
  totalComponents: number;
  totalTemplates: number;
  componentsBySource: {
    [key: string]: number;
  };
  templatesBySource: {
    [key: string]: number;
  };
  errors: string[];
  duration: number;
  timestamp: Date;
}

/**
 * 数据收集器配置
 */
export interface CollectorConfig {
  // 传统模式选项（向后兼容）
  enableAntDesign: boolean;
  enableAntDesignPro: boolean;
  enableProComponents: boolean;
  enableAntDesignCharts: boolean;
  
  // 通用模式选项
  useUniversalScraper: boolean; // 使用通用抓取器
  enabledDataSources?: string[]; // 指定启用的数据源 ID
  
  // 其他配置
  batchSize: number;
  maxRetries: number;
  retryDelay: number;
  clearExistingData: boolean;
  enableIncrementalUpdate: boolean; // 启用增量更新
  forceUpdate: boolean; // 强制更新所有数据
}

/**
 * 数据收集任务调度器
 */
export class DataCollector extends EventEmitter {
  private repositories?: RepositoryFactory;
  private config: CollectorConfig;
  private isRunning = false;

  constructor(repositories?: RepositoryFactory, config?: Partial<CollectorConfig>) {
    super();
    this.repositories = repositories;
    this.config = {
      enableAntDesign: true,
      enableAntDesignPro: true,
      enableProComponents: true,
      enableAntDesignCharts: true,
      useUniversalScraper: false, // 默认使用传统模式
      batchSize: 50,
      maxRetries: 3,
      retryDelay: 2000,
      clearExistingData: false,
      enableIncrementalUpdate: true, // 默认启用增量更新
      forceUpdate: false,
      ...config,
    };
  }

  /**
   * 开始数据收集
   */
  async collect(): Promise<CollectionResult> {
    if (this.isRunning) {
      throw new Error('数据收集任务正在运行中');
    }

    this.isRunning = true;
    const startTime = Date.now();
    
    const result: CollectionResult = {
      success: false,
      totalComponents: 0,
      totalTemplates: 0,
      componentsBySource: {},
      templatesBySource: {},
      errors: [],
      duration: 0,
      timestamp: new Date(),
    };

    try {
      this.log('🚀 开始全面数据收集任务...');
      
      // 初始化进度
      this.emitProgress({
        stage: '初始化',
        current: 0,
        total: 100,
        currentTask: '准备数据收集环境',
        message: '正在初始化数据收集器...',
        completed: [],
        errors: [],
      });

      // 1. 清理现有数据（如果配置了）
      if (this.config.clearExistingData && this.repositories) {
        this.emitProgress({
          stage: '清理数据',
          current: 5,
          total: 100,
          currentTask: '清理现有数据',
          message: '正在清理数据库中的现有数据...',
          completed: [],
          errors: [],
        });

        await this.clearExistingData();
        this.log('🗑️ 现有数据已清理');
      }

      // 2. 创建抓取器实例
      const scrapers = this.createScrapers();
      const totalTasks = scrapers.length;
      let completedTasks = 0;
      const completedTaskNames: string[] = [];

      // 3. 执行数据抓取
      for (const scraper of scrapers) {
        try {
          this.emitProgress({
            stage: '数据抓取',
            current: Math.round((completedTasks / totalTasks) * 60) + 10,
            total: 100,
            currentTask: scraper.constructor.name,
            message: `正在运行 ${scraper.constructor.name}...`,
            completed: completedTaskNames,
            errors: result.errors,
          });

          // 监听抓取进度
          scraper.on('progress', (progress) => {
            this.emitProgress({
              stage: '数据抓取',
              current: Math.round((completedTasks / totalTasks) * 60) + 10,
              total: 100,
              currentTask: scraper.constructor.name,
              message: `${scraper.constructor.name}: ${progress.message}`,
              completed: completedTaskNames,
              errors: result.errors,
            });
          });

          const scrapingResult = await scraper.scrape();
          
          if (scrapingResult.success) {
            this.log(`✅ ${scraper.constructor.name} 完成: 收集 ${scrapingResult.count} 项数据`);
            completedTaskNames.push(scraper.constructor.name);
            
            // 保存数据到数据库
            await this.saveScrapingResult(scraper.constructor.name, scrapingResult, result);
            
          } else {
            result.errors.push(...scrapingResult.errors);
            this.error(`❌ ${scraper.constructor.name} 失败: ${scrapingResult.errors.join(', ')}`);
          }

          completedTasks++;

        } catch (error) {
          const errorMsg = `${scraper.constructor.name} 执行失败: ${error instanceof Error ? error.message : String(error)}`;
          result.errors.push(errorMsg);
          this.error(errorMsg);
          completedTasks++;
        }
      }

      // 4. 数据统计和验证
      this.emitProgress({
        stage: '完成统计',
        current: 90,
        total: 100,
        currentTask: '数据统计',
        message: '正在统计收集结果...',
        completed: completedTaskNames,
        errors: result.errors,
      });

      await this.updateStatistics(result);

      result.success = result.errors.length === 0 || (result.totalComponents > 0 || result.totalTemplates > 0);
      
      this.emitProgress({
        stage: '完成',
        current: 100,
        total: 100,
        currentTask: '数据收集完成',
        message: `收集完成: ${result.totalComponents} 个组件, ${result.totalTemplates} 个模板`,
        completed: completedTaskNames,
        errors: result.errors,
      });

      this.log(`🎉 数据收集完成! 组件: ${result.totalComponents}, 模板: ${result.totalTemplates}`);

    } catch (error) {
      const errorMsg = `数据收集过程发生错误: ${error instanceof Error ? error.message : String(error)}`;
      result.errors.push(errorMsg);
      this.error(errorMsg);
    } finally {
      this.isRunning = false;
    }

    result.duration = Date.now() - startTime;
    return result;
  }

  /**
   * 创建抓取器实例
   */
  private createScrapers(): Array<AntDesignScraper | AntDesignProScraper | ProComponentsScraper | AntDesignChartsScraper | UniversalScraper> {
    const scrapers: Array<AntDesignScraper | AntDesignProScraper | ProComponentsScraper | AntDesignChartsScraper | UniversalScraper> = [];

    // 优先使用通用抓取器
    if (this.config.useUniversalScraper) {
      this.log('🎆 使用通用抓取器模式');
      const universalScraper = new UniversalScraper(this.config.enabledDataSources);
      scrapers.push(universalScraper);
      return scrapers;
    }

    // 传统模式：单独的抓取器
    this.log('🔍 使用传统抓取器模式');
    
    if (this.config.enableAntDesign) {
      scrapers.push(new AntDesignScraper());
    }

    if (this.config.enableAntDesignPro) {
      scrapers.push(new AntDesignProScraper());
    }

    if (this.config.enableProComponents) {
      scrapers.push(new ProComponentsScraper());
    }

    if (this.config.enableAntDesignCharts) {
      scrapers.push(new AntDesignChartsScraper());
    }

    return scrapers;
  }

  /**
   * 清理现有数据
   */
  private async clearExistingData(): Promise<void> {
    if (!this.repositories) {
      this.warn('无数据库连接，跳过数据清理');
      return;
    }

    try {
      // 清理相关表的数据
      await ComponentImport.destroy({ where: {} });
      await ComponentExample.destroy({ where: {} });
      await ComponentProp.destroy({ where: {} });
      await Component.destroy({ where: {} });
      await Template.destroy({ where: {} });
      
      this.log('✅ 现有数据清理完成');
    } catch (error) {
      this.error(`清理数据失败: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  /**
   * 保存抓取结果
   */
  private async saveScrapingResult(
    scraperName: string, 
    scrapingResult: ScrapingResult, 
    collectionResult: CollectionResult
  ): Promise<void> {
    if (!this.repositories) {
      this.warn('无数据库连接，跳过数据保存');
      return;
    }

    try {
      let componentCount = 0;
      let templateCount = 0;

      // 区分组件和模板数据
      for (const item of scrapingResult.data) {
        if (this.isComponentData(item)) {
          await this.saveComponent(item as ComponentData);
          componentCount++;
        } else if (this.isTemplateData(item)) {
          await this.saveTemplate(item as TemplateData);
          templateCount++;
        }
      }

      // 更新统计
      collectionResult.componentsBySource[scraperName] = componentCount;
      collectionResult.templatesBySource[scraperName] = templateCount;
      collectionResult.totalComponents += componentCount;
      collectionResult.totalTemplates += templateCount;

      this.log(`💾 ${scraperName} 数据保存完成: ${componentCount} 组件, ${templateCount} 模板`);

    } catch (error) {
      const errorMsg = `保存 ${scraperName} 数据失败: ${error instanceof Error ? error.message : String(error)}`;
      collectionResult.errors.push(errorMsg);
      this.error(errorMsg);
    }
  }

  /**
   * 判断是否为组件数据
   */
  private isComponentData(item: any): boolean {
    return item && typeof item.name === 'string' && Array.isArray(item.props);
  }

  /**
   * 判断是否为模板数据
   */
  private isTemplateData(item: any): boolean {
    return item && typeof item.name === 'string' && typeof item.code === 'string' && typeof item.framework === 'string';
  }

  /**
   * 保存组件数据（增量更新）
   */
  private async saveComponent(componentData: ComponentData): Promise<void> {
    try {
      const converted = DataConverter.convertComponent(componentData);
      
      // 检查是否已存在该组件
      let existingComponent = await Component.findOne({ 
        where: { name: converted.component.name } 
      });
      
      let componentId: number;
      
      if (existingComponent) {
        if (!this.config.forceUpdate && this.config.enableIncrementalUpdate) {
          // 增量更新模式：检查是否需要更新
          const needsUpdate = await this.shouldUpdateComponent(existingComponent, converted.component);
          if (!needsUpdate) {
            this.log(`⏩ 跳过组件 ${componentData.name}: 数据未更改`);
            return;
          }
        }
        
        // 更新现有组件
        await existingComponent.update({
          description: converted.component.description,
          version: converted.component.version,
          search_keywords: converted.component.search_keywords
        });
        componentId = existingComponent.id;
        
        // 清理现有关联数据
        await ComponentProp.destroy({ where: { component_id: componentId } });
        await ComponentExample.destroy({ where: { component_id: componentId } });
        await ComponentImport.destroy({ where: { component_id: componentId } });
        
        this.log(`🔄 更新组件 ${componentData.name}`);
      } else {
        // 创建新组件
        const newComponent = await Component.create(converted.component);
        componentId = newComponent.id;
        this.log(`➕ 新增组件 ${componentData.name}`);
      }

      // 创建或更新属性
      if (converted.props.length > 0) {
        const props = converted.props.map(prop => ({ ...prop, component_id: componentId }));
        await ComponentProp.bulkCreate(props);
      }

      // 创建或更新示例
      if (converted.examples.length > 0) {
        const examples = converted.examples.map(example => ({ ...example, component_id: componentId }));
        await ComponentExample.bulkCreate(examples);
      }

      // 创建或更新导入信息
      if (converted.imports.length > 0) {
        const imports = converted.imports.map(importItem => ({ ...importItem, component_id: componentId }));
        await ComponentImport.bulkCreate(imports);
      }

    } catch (error) {
      this.error(`保存组件 ${componentData.name} 失败: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  /**
   * 保存模板数据（增量更新）
   */
  private async saveTemplate(templateData: TemplateData): Promise<void> {
    try {
      const converted = DataConverter.convertTemplate(templateData);
      
      // 检查是否已存在该模板
      const existingTemplate = await Template.findOne({
        where: { name: converted.name }
      });
      
      if (existingTemplate) {
        if (!this.config.forceUpdate && this.config.enableIncrementalUpdate) {
          // 增量更新模式：检查是否需要更新
          const needsUpdate = await this.shouldUpdateTemplate(existingTemplate, converted);
          if (!needsUpdate) {
            this.log(`⏩ 跳过模板 ${templateData.name}: 数据未更改`);
            return;
          }
        }
        
        // 更新现有模板
        await existingTemplate.update(converted);
        this.log(`🔄 更新模板 ${templateData.name}`);
      } else {
        // 创建新模板
        await Template.create(converted);
        this.log(`➕ 新增模板 ${templateData.name}`);
      }
    } catch (error) {
      this.error(`保存模板 ${templateData.name} 失败: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  /**
   * 检查组件是否需要更新
   */
  private async shouldUpdateComponent(existingComponent: any, newData: any): Promise<boolean> {
    // 比较关键字段是否有变化
    const fieldsToCheck = ['description', 'version', 'search_keywords'];
    
    for (const field of fieldsToCheck) {
      if (existingComponent[field] !== newData[field]) {
        this.log(`🔄 组件 ${existingComponent.name} 的字段 ${field} 有更改`);
        return true;
      }
    }
    
    // 检查更新时间（如果距离上次更新超过一周，则强制更新）
    const oneWeekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
    if (existingComponent.updated_at < oneWeekAgo) {
      this.log(`🔄 组件 ${existingComponent.name} 超过一周未更新，进行刷新`);
      return true;
    }
    
    return false;
  }
  
  /**
   * 检查模板是否需要更新
   */
  private async shouldUpdateTemplate(existingTemplate: any, newData: any): Promise<boolean> {
    // 比较关键字段是否有变化
    const fieldsToCheck = ['description', 'template_code', 'dependencies'];
    
    for (const field of fieldsToCheck) {
      if (field === 'dependencies') {
        // 数组类型的比较
        const existing = JSON.stringify(existingTemplate[field] || []);
        const newVal = JSON.stringify(newData[field] || []);
        if (existing !== newVal) {
          this.log(`🔄 模板 ${existingTemplate.name} 的字段 ${field} 有更改`);
          return true;
        }
      } else if (existingTemplate[field] !== newData[field]) {
        this.log(`🔄 模板 ${existingTemplate.name} 的字段 ${field} 有更改`);
        return true;
      }
    }
    
    // 检查更新时间
    const oneWeekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
    if (existingTemplate.updated_at < oneWeekAgo) {
      this.log(`🔄 模板 ${existingTemplate.name} 超过一周未更新，进行刷新`);
      return true;
    }
    
    return false;
  }
  private async updateStatistics(result: CollectionResult): Promise<void> {
    if (!this.repositories) {
      return;
    }

    try {
      // 获取最新的统计数据
      const componentCount = await Component.count();
      const templateCount = await Template.count();
      
      result.totalComponents = componentCount;
      result.totalTemplates = templateCount;
      
      this.log(`📊 最终统计: ${componentCount} 个组件, ${templateCount} 个模板`);
    } catch (error) {
      this.error(`更新统计失败: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  /**
   * 发出进度事件
   */
  private emitProgress(progress: CollectionProgress): void {
    this.emit('progress', progress);
  }

  /**
   * 记录日志
   */
  private log(message: string): void {
    console.log(`[DataCollector] ${message}`);
  }

  /**
   * 记录警告
   */
  private warn(message: string): void {
    console.warn(`[DataCollector] ${message}`);
  }

  /**
   * 记录错误
   */
  private error(message: string): void {
    console.error(`[DataCollector] ${message}`);
  }

  /**
   * 停止收集任务
   */
  stop(): void {
    if (this.isRunning) {
      this.log('🛑 停止数据收集任务...');
      this.isRunning = false;
    }
  }

  /**
   * 获取收集状态
   */
  getStatus(): { isRunning: boolean; config: CollectorConfig } {
    return {
      isRunning: this.isRunning,
      config: { ...this.config }
    };
  }
}